import { ICopy } from "@/models/execute/ICopy";

export class Queue<T> implements ICopy {

    private elements?: Array<T>;
    private _size: number;

    public constructor(capacity?: number) {
        this.elements = new Array<T>();
        this._size = capacity ?? 10;
    }
    copyValue(valueObj: any): void {
        let obj = valueObj as Queue<T>;
        if(obj){
            this.elements = obj.elements;
            this._size = obj._size;
        }
    }

    public pushBack(o: T): T | undefined {
        if (o == null) {
            return undefined;
        }
        this.elements && this.elements.push(o);
        if ((this.elements?.length ?? 0) > this._size) {
            return this.elements?.shift();
        }
        return undefined;
    }

    public pushFront(o: T): T | undefined {
        if (o == null) {
            return undefined;
        }
        this.elements && this.elements.unshift(o);
        if ((this.elements?.length ?? 0) > this._size) {
            return this.elements?.pop();
        }
        return undefined;
    }

    public size(): number {
        return this.elements?.length ?? 0;
    }

    public empty(): boolean {
        return this.size() == 0;
    }

    public get(index: number): T | undefined {
        return this.elements && this.elements[index];
    }

    public clear() {
        delete this.elements;
        this.elements = new Array<T>();
    }

    public setSize(size: number) {
        this._size = size;
    }
    public getSize(): number {
        return this._size;
    }

    public setElement(elements: Array<T>|undefined) {
        if(elements) this.elements = elements;
    }
    public getElement(): Array<T> | undefined {
        return this.elements;
    }
}